use std::sync::Arc;

use axum::extract::{Path, State};
use axum::http::HeaderMap;
use axum::{Json, Router};
use axum::routing::{get, post};
use serde_json::{from_value, Value};
use tokio::sync::Mutex;
use tracing::info;

use crate::app_state::AppState;
use crate::controller::point_controller::get_machine_index;
use crate::dto::point_group_dto::{AddPointGroupDto, UpdatePointGroupDto};
use crate::entity::pointgroups;
use crate::util_entity::anyhow_res::{json_success_response, JsonResult};
pub fn route() -> Router<Arc<Mutex<AppState>>> {
    Router::new()
        .route("/GetAllPointGroups", get(get_all_point_groups))
        .route("/AddPointGroup", post(add_point_group))
        .route("/GetPointGroupById/:id", get(get_point_group_by_id))
        .route("/UpdatePointGroup", post(update_point_group))
}

pub async fn get_all_point_groups(State(app_state): State<Arc<Mutex<AppState>>>, headers: HeaderMap) -> JsonResult<Value> {
    let machine_index = get_machine_index(headers);
    info!("machine_index : {}", machine_index);
    let point_groups = app_state.lock().await.point_group_repo.get_all_point_groups_async(machine_index).await?;
    Ok(json_success_response(point_groups))
}

pub async fn add_point_group(
    State(app_state): State<Arc<Mutex<AppState>>>,
    headers: HeaderMap,
    Json(payload): Json<Value>,
) -> JsonResult<Value> {
    let machine_index = get_machine_index(headers);
    info!("machine_index : {}", machine_index);
    let param : AddPointGroupDto= from_value(payload)?;
    let point_group = app_state.lock().await.point_group_repo.add_point_group_async(machine_index, param).await?;
    Ok(json_success_response(point_group))
}

// GetPointGroupById/1
pub async fn get_point_group_by_id(
    State(app_state): State<Arc<Mutex<AppState>>>,
    headers: HeaderMap,
    Path(id): Path<i32>,
) -> JsonResult<Value> {
    let machine_index = get_machine_index(headers);
    info!("machine_index : {}", machine_index);
    let point_group = app_state.lock().await.point_group_repo.get_point_group_by_id_async(machine_index, id).await?;
    Ok(json_success_response(point_group))
}
// UpdatePointGroup
pub async fn update_point_group(
    State(app_state): State<Arc<Mutex<AppState>>>,
    headers: HeaderMap,
    Json(payload): Json<Value>,
) -> JsonResult<Value> {
    let machine_index = get_machine_index(headers);
    info!("machine_index : {}", machine_index);
    let param : UpdatePointGroupDto= from_value(payload)?;
    app_state.lock().await.point_group_repo.update_point_group_and_points(machine_index,param.id,param.base,param.points).await?;
    Ok(json_success_response("更新成功"))
}